#include "/root/mylib/project/public/_public.h"

using namespace idc;

struct st_stcode
{
    char Provname[10]; // 省
    char obtid[11];    // 站号
    char obtname[31];  // 站名
    double lat;        // 纬度
    double lon;        // 经度
    double height;     // 海拔高度
};
list<st_stcode> stcodelist;

struct st_surfdata
{
    char obtid[11];    // 站点代码
    char datetime[21]; // 数据时间，数据时间：格式yyyymmddhh24miss，精确到分钟，秒固定填00。
    int t;             // 气温，单位：0.1摄氏度
    int p;             // 气压，0.1百帕
    int u;             // 相对湿度，0-100之间的值
    int wd;            // 风向，0-360之间的值
    int wf;            // 风速：0-100之间的值
    int r;             // 降雨量：0.1mm
    int vis;           // 能见度：0.1米
};
list<st_surfdata> surfdatalist;

// 从站点参数文件中加载站点参数，存放在容器中
bool LoadSTCode(const string &inifile);
void crtsurfdata(); // 根据stlist容器中的站点参数，生成站点观测数据，存放在datalist中。
bool crtsurffile(const string &outpath, const string &datafmt);

char datetime[21];
clogfile logfile;
cpactive pactive;

void Exit(int signum);

int main(int argc, char *argv[])
{
    if (argc != 5)
    {
        // 帮助文档
        cout << "Using:./crtsurfdata inifile outpath logfile\n";
        cout << "Examples:/root/mylib/project/tools/bin/procctl 60 /root/mylib/project/idc/bin/crtsurfdata /root/mylib/project/idc/ini/stcode.ini /tmp/idc/surfdata /log/idc/crtsurfdata.log csv,xml,json\n\n";
        cout << "inifile  气象站点参数文件名。\n";
        cout << "outpath  气象站点数据文件存放的目录。\n";
        cout << "logfile  本程序运行的日志文件名。\n";
        cout << "datafmt  输出数据文件的格式，支持csv、xml和json，中间用逗号分隔。\n\n";
        return -1;
    }
    // // 设置信号,在shell状态下可用 "kill + 进程号" 正常终止些进程。
    // 但请不要用 "kill -9 +进程号" 强行终止。
    closeallsign();
    signal(2, Exit);
    signal(15, Exit);
    pactive.init(10,"crtsurfdata");

    if (logfile.open(argv[3]) == false)
    {
        cout << "logfile open %s failed.\n", argv[3];
        return -1;
    }

    logfile.write("crtsurfdata 开始运行。\n");

    // 从站点参数文件中加载站点参数，存放在容器中
    if (LoadSTCode(argv[1]) == false)
    {
        logfile.write("LoadSTCode(%s) failed.\n", argv[1]);
        Exit(-1);
    }
    memset(datetime, 0, sizeof(datetime));
    ltime(datetime, "yyyymmddhh24miss");
    strncpy(datetime + 12, "00", 2);
    // 2）根据stlist容器中的站点参数，生成站点观测数据（随机数），生成后的数据存放于容器中；
    crtsurfdata();

    // 3）把容器datalist中的气象观测数据写入文件，outpath-数据文件存放的目录；datafmt-数据文件的格式，取值：csv、xml和json。
    if (strstr(argv[4], "csv") != 0)
        crtsurffile(argv[2], "csv");
    if (strstr(argv[4], "xml") != 0)
        crtsurffile(argv[2], "xml");
    if (strstr(argv[4], "json") != 0)
        crtsurffile(argv[2], "json");

    logfile.write("crtsurfdata 运行结束。\n");

    return 0;
}

void Exit(int signum)
{
    logfile.write("程序退出,signum=%d\n", signum);
    exit(0);
}

bool LoadSTCode(const string &inifile)
{
    cifile ifile;
    if (ifile.open(inifile) == false)
    {
        logfile.write("LoadSTCode ifile.open(%s) failed.\n", inifile.c_str());
        return false;
    }
    string stdata; // 存储读到的数据
    ifile.readline(stdata);

    st_stcode stcode;
    ccmdstr cmdstr;
    while (ifile.readline(stdata))
    {
        memset(&stcode, 0, sizeof(stcode));
        cmdstr.splittocmd(stdata, ",");
        cmdstr.getvalue(0, stcode.Provname, 10);
        cmdstr.getvalue(1, stcode.obtid, 11);
        cmdstr.getvalue(2, stcode.obtname, 30);
        cmdstr.getvalue(3, stcode.lat);
        cmdstr.getvalue(4, stcode.lon);
        cmdstr.getvalue(5, stcode.height);

        stcodelist.push_back(stcode);
    }
    // 把容器中全部的数据写入日志。
    //  for (auto &aa:stcodes)
    //  {
    //     logfile.write("provna me=%s,obtid=%s,obtname=%s,lat=%.2f,lon=%.2f,height=%.2f\n",\
    //                         aa.Provname,aa.obtid,aa.obtname,aa.lat,aa.lon,aa.height);
    //  }
    return true;
}

void crtsurfdata()
{
    srand(time(0));
    st_surfdata stsurfdata;
    for (auto &aa : stcodelist)
    {
        memset(&stsurfdata, 0, sizeof(stsurfdata));
        strcpy(stsurfdata.obtid, aa.obtid);
        strcpy(stsurfdata.datetime, datetime);
        stsurfdata.t = rand() % 350;             // 气温：单位，0.1摄氏度。   0-350之间。 可犯可不犯的错误不要犯。
        stsurfdata.p = rand() % 265 + 10000;     // 气压：0.1百帕
        stsurfdata.u = rand() % 101;             // 相对湿度， 0-100之间的值。
        stsurfdata.wd = rand() % 360;            // 风向，0-360之间的值。
        stsurfdata.wf = rand() % 150;            // 风速：单位0.1m/s。
        stsurfdata.r = rand() % 16;              // 降雨>量：0.1mm。
        stsurfdata.vis = rand() % 5001 + 100000; // 能见度：0.1米。

        surfdatalist.push_back(stsurfdata);
    }
    // 把容器中全部的数据写入日志，仅为测试。
    // for (auto &aa : surfdatalist)
    // {
    //     logfile.write("%s,%s,%.1f,%.1f,%d,%d,%.1f,%.1f,%.1f\n",
    //                   aa.obtid, aa.datetime, aa.t / 10.0, aa.p / 10.0, aa.u, aa.wd, aa.wf / 10.0, aa.r / 10.0, aa.vis / 10.0);
    // }
}

bool crtsurffile(const string &outpath, const string &datafmt)
{
    string strfilename = outpath + "/" + "SURF_ZH_" + datetime + "_" + to_string(getpid()) + "." + datafmt;

    cofile ofile;
    if (ofile.open(strfilename) == false)
    {
        logfile.write("crtsurffile ofile.open(%s) failed.\n", strfilename.c_str());
        return false;
    }

    if (datafmt == "xml")
    {
        ofile.writeline("<data>");
    }

    if (datafmt == "csv")
    {
        ofile.writeline("站点代码,数据时间,气温,气压,相对湿度,风向,风速,降雨量,能见度");
    }

    if (datafmt == "json")
    {
        ofile.writeline("{[");
    }

    for (auto &aa : surfdatalist)
    {
        if (datafmt == "csv")
            ofile.writeline("%s,%s,%.1f,%.1f,%d,%d,%.1f,%.1f,%.1f\n",
                            aa.obtid, aa.datetime, aa.t / 10.0, aa.p / 10.0, aa.u, aa.wd, aa.wf / 10.0, aa.r / 10.0, aa.vis / 10.0);

        if (datafmt == "xml")
            ofile.writeline("<obtid>%s</obtid><ddatetime>%s</ddatetime><t>%.1f</t><p>%.1f</p><u>%d</u>"
                            "<wd>%d</wd><wf>%.1f</wf><r>%.1f</r><vis>%.1f</vis><endl/>\n",
                            aa.obtid, aa.datetime, aa.t / 10.0, aa.p / 10.0, aa.u, aa.wd, aa.wf / 10.0, aa.r / 10.0, aa.vis / 10.0);

        if (datafmt == "json")
        {
            ofile.writeline("{\"obtid\":\"%s\",\"ddatetime\":\"%s\",\"t\":\"%.1f\",\"p\":\"%.1f\","
                            "\"u\":\"%d\",\"wd\":\"%d\",\"wf\":\"%.1f\",\"r\":\"%.1f\",\"vis\":\"%.1f\"}",
                            aa.obtid, aa.datetime, aa.t / 10.0, aa.p / 10.0, aa.u, aa.wd, aa.wf / 10.0, aa.r / 10.0, aa.vis / 10.0);
        }

        if (datafmt == "xml")
        {
            ofile.writeline("</data>");
        }

        if (datafmt == "json")
        {
            ofile.writeline("]}");
        }
    }
    ofile.closeandrename();
    logfile.write("生成数据文件%s成功，数据时间%s，记录数%d。\n",strfilename.c_str(),datetime,surfdatalist.size());

    return true;
}